#!/usr/bin/env python
# coding=UTF-8
import random
import logging
import json
import time
import datetime
import copy
import urllib

import redisco
from redisco.containers import List, Hash

from tools import nsq_pub, json_encode
import dao

def get_last_data(reader, bid, uid, data):
    uid = str(uid)
    user_info = Hash("%s_%s" % (bid, uid))
    rid = user_info['rid']
    if not rid:
        rid = data.get("rid", "")
    room = Hash("r:%s" % rid)
    tdh = PinCiDao(rid, bid)
    last_put_user = tdh.room['last_put_user']
    last_put_card = tdh.room['last_put_card']
    if not last_put_card:
        last_put_card = []
    else:
        last_put_card = last_put_card.split(",")
    all_player_data = []
    db = dao.Game_DB()
    members = tdh.members
    for member in members:
        if member:
            p = Player(member, bid, rid)
            player_data = p.get_data()
            player_info = db.get_player(rid, uid)
            player_data['status'] = player_info['status']
            player_data['user_score'] = player_info['score']
            player_data['online'] = player_info['online']
            if member == uid:
                card_list = tdh.format_card(player_data['current_card'])
                #player_data['current_card'] = sorted(player_data['current_card'], key=lambda x:int(x), reverse=True)
                player_data['left_num'] = len(player_data['current_card'])
                player_data['current_card'] = card_list
                
            else:
                player_data['left_num'] = len(player_data['current_card'])
                player_data['current_card'] = []
            all_player_data.append(player_data)
        
    dealer = tdh.room['dealer']
    if not dealer:
        dealer = ''
    data = {"act":"get_last_data", 
            "last_put_user":last_put_user, 
            "last_put_card":last_put_card, 
            "game_round":room['game_round'],
            "all_round":room['all_round'],
            "dealer":dealer,
            "all_player_data":all_player_data,
            "rid":rid,
            "status":room['status'],
           }
    
    nsq_pub({"b":bid, "u":uid, "t":"game", "d":data})
    stop_pop_user = tdh.room['stop_pop_user']
    stop_pop_act = tdh.room['stop_pop_act']
    if stop_pop_user:
        if stop_pop_user == uid:
            my_seat = members.index(uid)
            pre_user = members[my_seat-1]
            tdh.notify_next_user(pre_user)
        else:
            if not last_put_user:
                put_type = "free"
            else:
                put_type = "follow"
            nsq_pub({"b":bid, "u":uid, "t":"game", "d":{"act":"turn_put", "put_type":put_type, "uid":stop_pop_user, "rid":rid, "valid_list":[], "tips_list":[], "last_put_card":last_put_card, "last_put_type":"", "last_put_point":""}})
        
        
class Player():
    def __init__(self, uid, bid='', rid='', first=False):
        self.uid = uid
        self.bid = bid
        self.rid = rid
        if first:
            redisco.connection.delete("p:%s:%s:%s:current_card" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:out_card" % (bid, uid, rid))
            #redisco.connection.delete("p:%s:%s:%s:bomb" % (bid, uid, rid))
            #redisco.connection.delete("p:%s:%s:%s:put_num" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s" % (bid, uid, rid))
            self.score = Hash("p:%s:%s:%s" % (bid, uid, rid))
            self.score['score'] = 0
            self.score['card_score'] = 0
            self.score['final_card_score'] = 0
            self.score['prize_num'] = 0
            self.score['user_prize'] = 0
        else:
            self.score = Hash("p:%s:%s:%s" % (bid, uid, rid))
        self.current_card = List("p:%s:%s:%s:current_card" % (bid, uid, rid))
        self.out_card = List("p:%s:%s:%s:out_card" % (bid, uid, rid))
        #self.bomb = List("p:%s:%s:%s:bomb" % (bid, uid, rid))
        #self.put_num = List("p:%s:%s:%s:put_num" % (bid, uid, rid))
    
    def clear(self):
        redisco.connection.delete("p:%s:%s:%s:current_card" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s:out_card" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s" % (self.bid, self.uid, self.rid))
        
    def get_data(self):
        return {"uid":self.uid,
                "current_card":self.current_card.members,
                "score":self.score['score'],
                "prize_num":self.score['prize_num'],
                "user_prize":self.score['user_prize'],
                "card_score":self.score['card_score'],
                "final_card_score":self.score['final_card_score'],
                "ranking":self.score['ranking'],
                }

class PinCiDao():
    '''万安拼刺刀'''
    def __init__(self, rid, bid, dealer=None):
        self.rid = str(rid)
        if dealer:
            redisco.connection.delete("r:%s:current_card" % rid)
            redisco.connection.delete("r:%s:mid" % rid)
            redisco.connection.delete("r:%s:win_user" % rid)
            self.room = Hash("r:%s" % rid)
            self.room['dealer'] = dealer
            self.room['last_get_user'] = dealer
            self.room['last_put_user'] = ''
            self.room['stop_pop_user'] = ''
            self.room['stop_pop_act'] = ''
            self.room['current_score'] = 0
            self.room['bottom_uid'] = ''
        else:
            self.room = Hash("r:%s" % rid)
        self.current_card = List("r:%s:current_card" % rid)
        self.win_user = List("r:%s:win_user" % rid)
        self.bid = bid
        l = List("r:%s:p" % rid)
        self.members = l.members
    
    def incr_mid(self):
        return redisco.connection.incr("r:%s:mid" % self.rid)
    
    def get_card_point(self, c):
        '''获取某张扑克牌的点数'''
        return int(c)/10
    
    def trans_card(self, card):
        '''转换手牌列表,去掉花色'''
        res = []
        card.sort()
        for c in card:
            card_point = self.get_card_point(c)
            res.append(card_point)
        return res
    
    def format_card(self, all_card):
        #logging.info(str(all_card))
        card_list = {}
        all_card.sort()
        small_joker_cnt = all_card.count('141')
        big_joker_cnt = all_card.count('151')
        other_joker_cnt = all_card.count('161')
        if (small_joker_cnt+big_joker_cnt+other_joker_cnt) >= 4:
            merge_flag = True
        else:
            merge_flag = False
        for c in all_card:
            d = int(c)/10
            if d >= 14 and merge_flag:
                d = '14'
            else:
                d = str(d)
            if d in card_list:
                card_list[d].append(c)
            else:
                card_list[d] = [c]
        return card_list
    
    def is_pair(self, card_list):
        '''对子'''
        if len(card_list) == 2 and (len(set(card_list)) == 1 or all(map(lambda x:x>=14, card_list))):
            return 'pair', len(card_list), card_list[0]
        return False, 0, 0
    
    
    def is_bomb(self, card_list):
        '''炸弹'''
        if len(card_list) >= 4:
            if len(set(card_list)) == 1 or all(map(lambda x:x>=14, card_list)):
                return 'bomb', len(card_list), card_list[0]
        return False, 0, 0
    
    def is_triple(self, card_list):
        '''三条'''
        if len(card_list) == 3 and (len(set(card_list)) == 1 or all(map(lambda x:x>=14, card_list))):
            return 'triple', len(card_list), card_list[0]
        return False, 0, 0
    
    def get_card_score(self, card):
        '''计算出牌中的分数'''
        card_list = self.trans_card(card)
        score = 0
        for c in card_list:
            if c == 3:
                score += 5
            elif c == 8:
                score += 10
            elif c == 11:
                score += 10
        return score
    
    def get_card_prize(self, card):
        '''计算出牌中的奖'''
        prize_conf = {"7":1, "8":2, "9":3, "10":4, "11":5, "12":6, "13":7, "14":8, "15":9,
                      "16":10, "17":11, "18":12, "19":13, "20":14, "21":15, "22":16, "23":17, "24":18,}
        joker_prize_conf = {"4":1,"5":2,"6":[3,3,3,3,4,5],"7":7, "8":10, "9":12, "10":14, "11":16, "12":18, "13":20, "14":22, 
                            "15":24, "16":26, "18":28, "19":30, "20":32, "21":34, "22":36, "23":38, "24":40}
        pure_joker_prize_conf = {"4":2,"5":3,"6":6,"7":7, "8":10, "9":12, "10":14, "11":16, "12":18, "13":20, "14":22, 
                                 "15":24, "16":26, "18":28, "19":30, "20":32, "21":34, "22":36, "23":38, "24":40}
        card_list = self.trans_card(card)
        card_type, card_num, card_point = self.is_bomb(card_list)
        bomb_num = str(card_num)
        if not card_type:
            return 0
        if card_point >= 14:
            if len(list(set(card_list))) >= 2:
                if bomb_num == 6:
                    cnt_141 = card.count('141')
                    cnt_151 = card.count('151')
                    cnt_161 = card.count('161')
                    if cnt_141 > cnt_151:
                        bm = cnt_141 + cnt_161
                    else:
                        bm = cnt_151 + cnt_161
                    return joker_prize_conf[bomb_num][bm]
                return joker_prize_conf[bomb_num]
            else:
                return pure_joker_prize_conf[bomb_num]

        return prize_conf.get(bomb_num, 0)
    
    def get_card_type(self, card):
        card_list = self.trans_card(card)
        card_len = len(card_list)
        if card_len >= 4:
            res = self.is_bomb(card_list)
            if res[0]:
                return res
        elif card_len == 3:
            #三不带
            res = self.is_triple(card_list)
            if res[0]:
                return res
        elif card_len == 2:
            res = self.is_pair(card_list)
            if res[0]:
                return res
        elif card_len == 1:
            return 'single', 1, card_list[0]
        return False, 0, 0
    
    def compare_card(self, card1, card2):
        #判断card2是否比card1牌型大
        card_type2, len2, point2 = self.get_card_type(card2)
        card_type1, len1, point1 = self.get_card_type(card1)
        if card_type1 == card_type2:
            #相同类型的牌
            if card_type1 == 'bomb':
                if len2 > len1:
                    return True
                elif len2 == len1 and point2 > point1:
                    return True
            else:
                if point2 > point1:
                    return True
        elif card_type2 == 'bomb':
            return True
        return False
    
    def get_card_by_point(self, card, card_point):
        res = []
        for c in card:
            if self.get_card_point(c) == card_point:
                res.append(c)
        return res
    
    def get_bomb_card(self, card, bomb_point=0, card_num=4):
        '''取手牌中大于bomb_point的炸弹, 为0则返回所有炸弹'''
        res = []
        tips_list = []
        card_list = self.trans_card(card)
        rocket = []
        for cc in card:
            if int(cc)/10 >= 14:
                rocket.append(cc)
        bomb_list = []
        for c in set(card_list):
            if c >= 14:
                continue
            c_cnt = card_list.count(c) 
            if (c_cnt == card_num and c > bomb_point) or c_cnt > card_num:
                bomb_list.append(c)
        if (len(rocket) == card_num and bomb_point < 14) or len(rocket) > card_num:
            tips_list.append(rocket)
            res.extend(rocket)
            
        for card_point in bomb_list:
            tips_card = self.get_card_by_point(card, card_point)
            res.extend(tips_card)
            tips_list.append(tips_card)
        return res, tips_list

    def get_single_card(self, card, single_point=0):
        '''取手牌中大于single_point点数的单张牌'''
        res = []
        tips_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if c > single_point and card_list.count(c) == 1:
                rs = self.get_card_by_point(card, c)
                res.extend(rs)
                tips_card = rs[:1]
                tips_list.append(tips_card)
        return res, tips_list
    
    def get_pair_card(self, card, pair_point=0):
        '''取手牌中大于pair_point点数的对子扑克牌'''
        res = []
        tips_list = []
        pair_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if card_list.count(c) == 2:
                if c > pair_point:
                    pair_list.append(c)
        for card_point in pair_list:
            tips_card = self.get_card_by_point(card, card_point)
            res.extend(tips_card)
            tips_list.append(tips_card)
        return res, tips_list
    
    def get_triple_card(self, card, triple_point=0):
        res = []
        tips_list = []
        triple_list = []
        card_list = self.trans_card(card)
        rocket = []
        for cc in card:
            if int(cc)/10 >= 14:
                rocket.append(cc)
        for c in set(card_list):
            if c >= 14:
                continue
            c_cnt = card_list.count(c)
            if c_cnt == 3 and c > triple_point:
                triple_list.append(c)
        if len(rocket) == 3 and triple_point < 14:
            tips_list.append(rocket)
            res.extend(rocket)

        for card_point in triple_list:
            tips_card = self.get_card_by_point(card, card_point)
            res.extend(tips_card)
            tips_list.append(tips_card)
        return res, tips_list
    
    def check_validate(self, card, card_type):
        return self.get_card_type(card)[0] == card_type

    def get_valid_card(self, current_card, last_put_card, last_put_type='', last_put_point=''):
        valid_card = []
        last_put_type, last_card_num, last_put_point = self.get_card_type(last_put_card)
        if last_put_type == 'single':
            valid_card = self.get_single_card(current_card, int(last_put_point))
        elif last_put_type == 'pair':
            valid_card = self.get_pair_card(current_card, int(last_put_point))
        elif last_put_type == 'triple':
            valid_card = self.get_triple_card(current_card, int(last_put_point))
        if last_put_type == 'bomb':
            valid_card = self.get_bomb_card(current_card, int(last_put_point), last_card_num)
        else:
            bomb_card = self.get_bomb_card(current_card, 0)
            valid_list = bomb_card[0]
            tips_list = bomb_card[1]
            if valid_card:
                valid_card[0].extend(valid_list)
                valid_card[1].extend(tips_list)
            else:
                valid_card = bomb_card
        return valid_card
    
    def start(self):
        self.room['status'] = 'start'
        game_round = int(self.room['game_round'])
        all_card = []
        for i in range(10, 140, 10):
                for j in range(1, 5):
                    all_card.append(str(i+j))
        
        random.shuffle(all_card)
        card_pack = self.room['card_pack']
        #几副牌,默认4个人6副牌
        if card_pack:
            card_pack = int(card_pack)
        else:
            card_pack = 6
        all_card *= card_pack
        
        add_joker = self.room['add_joker']
        #是否需要额外加王
        if add_joker:
            add_joker = int(add_joker)
        else:
            add_joker = 0
        joker = ['141', '151'] * card_pack
        random.shuffle(joker)
        all_card.extend(joker)
        if add_joker:
            all_card.extend(['161']*add_joker)
        random.shuffle(all_card)
        members = self.members
        all_card_num = len(all_card)
        player_cnt = len(members)
        if game_round == 1:
            dealer = random.choice(self.members)
            self.room['dealer'] = dealer
        else:
            dealer = self.room['dealer']
        player_card = []
        every_player_num = all_card_num/player_cnt
        for uid in members:
            player_card.append({"uid":uid, "left_num":every_player_num})
        
        user_card = {}
        for uid in members:
            user_card[uid] = []
            
        for i in range(every_player_num):
            for uid in members:
                user_card[uid].append(all_card.pop())
        
        for uid in members:
            mid = self.incr_mid()
            player = Player(uid, self.bid, self.rid, True)
            card = user_card[uid]
            card.sort()
            card.reverse()
            player.current_card.clear()
            player.current_card.extend(card)
            card_list = self.format_card(card)
                    
            #card_list = [str(x) for x in card]
            nsq_pub({"b":self.bid, "u":str(uid), "t":"game", "d":{"act":"game_start", "status":"start", "left_card":0, "rid":self.rid, "mid":mid, "dealer":dealer, "card":card_list, "game_round":self.room['game_round'], "all_round":self.room['all_round'], "player_card":player_card}})
        
        self.room['last_put_user'] = ''
        self.room['last_put_card'] = ''
        self.room['last_put_type'] = ''
        self.room['last_put_point'] = ''
        self.room['stop_pop_user'] = dealer
        self.current_card.clear()
        logging.info(u"房间rid:%s,game_round:%s,发牌结束,通知%s出牌" % (self.rid, self.room['game_round'], dealer))
        self.notify_keep_put(dealer)
        
    def notify_keep_put(self, uid):
        self.room['stop_pop_user'] = uid
        self.room['last_get_user'] = uid
        self.room['last_put_user'] = ''
        self.room['last_put_card'] = ''
        self.room['last_put_type'] = ''
        self.room['last_put_point'] = ''
        members = self.members
        current_score = int(self.room['current_score'])
        player = Player(uid, self.bid, self.rid)
        if current_score > 0:
            player.score['card_score'] = int(player.score['card_score']) + current_score
            self.room['current_score'] = 0
            logging.info(u"玩家%s大牌,桌面分数%s,更新后分数%s" % (uid, current_score, player.score['card_score']))
            for member in members:
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"tips_score", "rid":self.rid,"uid":uid, "card_score":player.score['card_score']}})
        
        all_card = player.current_card.members
        if all_card:
            card_list = self.format_card(all_card)
            for member in members:
                if member == uid:
                    tips_list = []
                    card_type, card_num, card_point = self.get_card_type(all_card)
                    if card_type:
                        tips_list.append(all_card)
                    else:
                        current_card = sorted(all_card, key=lambda x:int(x))
                        card_list = {}
                        for c in current_card:
                            d = str(int(c)/10)
                            if d in card_list:
                                card_list[d].append(c)
                            else:
                                card_list[d] = [c]
                        tips_list = sorted(card_list.values(), key=lambda x:len(x)) 
                    valid_list = all_card
                    current_card = card_list
                else:
                    valid_list = []
                    tips_list = []
                    current_card = []
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"turn_put", "current_card":current_card,"put_type":"free", "uid":uid, "valid_list":valid_list, "rid":self.rid, "tips_list":tips_list, "last_put_card":[], "last_put_type":"", "last_put_point":[]}})
        else:
            self.notify_next_user(uid)
            
    def notify_next_user(self, pre_user):
        members = self.members
        pre_user_seat = members.index(pre_user)
        next_user_seat = (pre_user_seat + 1) % len(members)
        next_user = members[next_user_seat]
        self.room['stop_pop_user'] = next_user
        last_put_user = self.room['last_put_user']
        if not last_put_user or next_user == last_put_user:
            #首次出牌或者过一圈没人能打起
            self.notify_keep_put(next_user)
            return
        else:
            last_put_card = self.room['last_put_card'].split(",")
            last_put_type = self.room['last_put_type']
            last_put_point = self.room['last_put_point']
            if last_put_point:
                last_put_point = int(last_put_point)
            #判断下家能否打牌,没有打牌则自动发送要不起,否则发送出牌通知
            #last_put_type, last_put_point = self.get_card_type(last_put_card)
            p = Player(next_user, self.bid, self.rid)
            current_card = p.current_card.members
            if not current_card:
                self.notify_next_user(next_user)
                return
            logging.info(u"判断下家是否有牌:%s, last_put_card:%s, type:%s, point:%s" % (next_user, str(last_put_card), last_put_type, str(last_put_point)))
            valid_card = self.get_valid_card(current_card, last_put_card, last_put_type, last_put_point)
            card_list = self.format_card(current_card)   
            for member in members:
                if member == next_user:
                    valid_list, tips_list = valid_card
                    logging.info(u"下家%s可出的牌有:valid_list:%s, tips_list:%s" % (member, str(valid_list), str(tips_list)))
                    valid_list = sorted(valid_list, key=lambda x:int(x))
                    tips_list = sorted(tips_list, key=lambda x:len(x))
                    #logging.info(u"下家%s可出的牌有:%s" % (member, str(tips_list)))
                    current_card = card_list
                else: 
                    #logging.info(u"=============member:%s,next_user:%s" % (member, next_user))
                    valid_list, tips_list = [], []
                    current_card = []
                nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"act":"turn_put", "current_card":current_card, "put_type":"follow", "uid":next_user, "rid":self.rid, "valid_list":valid_list, "tips_list":tips_list, "last_put_card":last_put_card, "last_put_type":last_put_type, "last_put_point":last_put_point}})
            
    
    def pass_card(self, uid, data={}):
        stop_pop_user = self.room['stop_pop_user']
        if uid != stop_pop_user:
            logging.error(u"pass,该%s打牌,不该%s" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        members = self.members
        mid = self.incr_mid()
        for member in members:
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"pass", "mid":mid, "uid":uid, "rid":self.rid}})
        self.notify_next_user(uid)
        
    def put_card(self, uid, data):
        uid = str(uid)
        stop_pop_user = self.room['stop_pop_user']
        if uid != stop_pop_user:
            logging.error(u"该%s出牌,不该%s" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = data['card']
        if not isinstance(card, list):
            card = card.split(",")
        card_type, card_num, card_point = self.get_card_type(card)
        logging.info(u"过炸检查用户牌型%s,%s" % (card_type, card_point))
        if not card_type:
            #牌型不符合
            logging.error(u"%s出牌不符合规范,%s" % (uid, ",".join(card)))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return 
        
        current_player = Player(uid, self.bid, self.rid)
        user_current_card = current_player.current_card.members
        for c in card:
            if c not in user_current_card:
                logging.error(u"出牌异常,用户%s没有该手牌,%s" % (uid, c))
                get_last_data('', self.bid, uid, {"rid":self.rid})
                return
        
        last_put_type = self.room['last_put_type']
        last_put_user = self.room['last_put_user']
        last_put_point = self.room['last_put_point']
        last_put_card = self.room['last_put_card']
        members = self.members
        if last_put_card:
            #跟上家的牌
            put_type = 'follow'
            card1 = last_put_card.split(",")
            if not self.compare_card(card1, card):
                logging.error(u"出牌异常,用户%s出牌牌不能大过上家,%s" % (uid, ",".join(card)))
                get_last_data('', self.bid, uid, {"rid":self.rid})
                return
        else:
            #自由出牌
            put_type = 'free'
        
        for c in card:
            current_player.current_card.remove(c, 1)
            current_player.out_card.append(c)
            #self.current_card.append(c)
        
        self.room['last_put_card'] = ",".join(card)
        self.room['last_put_type'] = card_type
        self.room['last_put_point'] = card_point
        self.room['last_put_user'] = uid
        user_left_card = current_player.current_card.members
        left_num = len(user_left_card)
        card_score = self.get_card_score(card)
        logging.info(u"出牌:%s,包含分数%s" % (",".join(card), card_score))
        current_score = int(self.room['current_score'])
        if card_score > 0:
            current_score += card_score
            self.room['current_score'] = current_score
            
        card_prize = self.get_card_prize(card)
        if card_prize > 0:
            user_prize = int(current_player.score['prize_num']) + card_prize
            current_player.score['prize_num'] = user_prize
        else:
            user_prize = current_player.score['prize_num']
        
        card_list = self.format_card(user_left_card)
        
        mid = self.incr_mid()
        for member in members:
            if member == str(uid):
                current_card = card_list
            else:
                current_card = []
                
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"put_card", "mid":mid, "current_card":current_card, "card_prize":card_prize, "user_prize":user_prize, "current_score":current_score, "put_type":put_type, "left_num":left_num, "uid":uid, "rid":self.rid, "card":card, "card_type":card_type}})
        
        if user_left_card:
            self.notify_next_user(uid)
        else:
            self.win_user.append(uid)
            win_user = self.win_user.members
            
            if win_user.index(uid) == 0:
                ranking = '1'
            elif win_user.index(uid) == 1:
                ranking = '2'
            elif win_user.index(uid) == 2:
                ranking = '3'
            else:
                ranking = '4'
            
            current_player.score['ranking'] = ranking
            for member in members:
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"put_over", "ranking":ranking, "uid":uid, "rid":self.rid}})
            
            current_score = int(self.room['current_score'])
            if current_score > 0:
                current_player.score['card_score'] = int(current_player.score['card_score']) + current_score
                self.room['current_score'] = 0
            logging.info(u"三游%s出完牌,剩余桌面分数%s" % (uid, current_score))
            if len(win_user)+1 == len(members):
                for member in self.members:
                    if member not in win_user:
                        self.room['bottom_uid'] = member
                        bottom_player = Player(member, self.bid, self.rid)
                        bottom_player.score['ranking'] = 4
                        break
                self.game_over()
            else:
                self.notify_next_user(uid)
    
                
    def game_over(self, winner='', from_dissmiss=False, duty_uid=''):
        dealer = self.room['dealer']
        self.room['status'] = 'over'
        db = dao.Game_DB()
        rules = {}
        gid = self.room['gid']
        if gid:
            rows = db.game_rule(gid)
        else:
            rows = db.room_rule(self.rid)
            gid = ""
        for row in rows:
            k = row['param']
            v = row['value']
            rules[k] = v
        game_round = self.room['game_round']
        if game_round:
            game_round = int(game_round)
        else:
            game_round = 1
            
        all_round = self.room['all_round']
        if all_round:
            all_round = int(all_round)
        else:
            all_round = 1
            
        overlord_double = False
        win_user = self.win_user.members
        if len(win_user) == 3:
            
            next_dealer = win_user[0]
            bottom_uid = self.room['bottom_uid']
            bottom_player = Player(bottom_uid, self.bid, self.rid)
            bottom_card = bottom_player.current_card.members
            bottom_card_score = self.get_card_score(bottom_card)
            third_uid = win_user[2]
            third_player = Player(third_uid, self.bid, self.rid)
            logging.info(u"最后一家的手牌牌分数%s, 手牌是:%s" % (bottom_card_score, ",".join(bottom_card)))
            if bottom_card_score:
                third_player.score['card_score'] = int(third_player.score['card_score']) + bottom_card_score
            
            all_user_prize = []
            for member in self.members:
                member_player = Player(member, self.bid, self.rid)
                member_player.score['final_card_score'] = member_player.score['card_score']
                all_user_prize.append(member_player.score['prize_num'])
            
            all_user_prize.sort()
            if len(set(all_user_prize)) == 2:
                sp, ep = 0, 0
                for c in set(all_user_prize):
                    if all_user_prize.count(c) == 3:
                        sp = c
                    else:
                        ep = c
                if ep > sp:
                    overlord_double = True
                    
            first_uid = win_user[0]
            first_player = Player(first_uid, self.bid, self.rid)    
            first_player.score['final_card_score'] = int(first_player.score['card_score']) + 40
            logging.info(u"第一家%s的牌分数+40, 后是:%s" % (bottom_uid, first_player.score['final_card_score']))
            bottom_player.score['final_card_score'] = int(bottom_player.score['card_score']) - 40
            logging.info(u"最后一家%s的牌分数-40, 后是:%s" % (bottom_uid, bottom_player.score['final_card_score']))
            
            for member in self.members:
                if member != first_uid:
                    member_player = Player(member, self.bid, self.rid)
                    member_card_score = int(member_player.score['final_card_score'])
                    give_score = member_card_score % 10
                    if give_score != 0:
                        member_player.score['final_card_score'] = int(member_player.score['final_card_score']) - give_score
                        logging.info(u"处理零分%s的牌分数-%s, 后是:%s" % (member, give_score, member_player.score['final_card_score']))
                        first_player.score['final_card_score'] = int(first_player.score['final_card_score']) + give_score
                        logging.info(u"处理零分头游%s的牌分数+%s, 后是:%s" % (first_uid, give_score, first_player.score['final_card_score']))
                        
            for member in self.members:
                member_player = Player(member, self.bid, self.rid)
                m_prize = int(member_player.score['prize_num'])
                user_prize = 0
                for mm in self.members:
                    if mm != member:
                        mm_player = Player(mm, self.bid, self.rid)
                        mm_prize = int(mm_player.score['prize_num'])
                        user_prize += (m_prize - mm_prize)
                        logging.info(u"计算%s-%s的奖分数: %s-%s" %(member, mm, m_prize, mm_prize))
                
                #霸王奖翻倍
                if overlord_double:
                    user_prize *= 2
                    
                logging.info(u"最终%s的奖分数: %s" %(member, user_prize))
                member_player.score['user_prize'] = user_prize
                
            for member in self.members:
                member_player = Player(member, self.bid, self.rid)
                card_score = int(member_player.score['final_card_score']) - 150
                user_prize = int(member_player.score['user_prize'])
                final_score = card_score/10 + user_prize*2
                member_player.score['score'] = final_score
                
                db.update_player(self.rid, member, final_score, 0)
                db.commit()
        else:
            next_dealer = dealer
        
        player_card = []
        for member in self.members:
            player_info = db.get_player(self.rid, member)
            member_player = Player(member, self.bid, self.rid)
            user_data = member_player.get_data()
            if member == dealer:
                is_dealer = 'y'
            else:
                is_dealer = 'n'
            user_data['is_dealer'] = is_dealer
            user_data['user_score'] = player_info['score']
            player_card.append(user_data)
            card_score = user_data['card_score']
            final_card_score = user_data['final_card_score']
            prize_num = user_data['prize_num']
            score = user_data['score']
            if int(score) >0:
                is_win = 1
            else:
                is_win = 0
            
            if from_dissmiss:
                is_win = 2
            
            db.add_room_log(0, 0, self.rid, game_round, member, score, card_score, prize_num, is_dealer, is_win, 0, "")
            db.commit()
        room_over = 'n'
        if from_dissmiss or game_round >= all_round:
            room_over = 'y'
        db.game_over(self.rid, game_round)
        db.commit()
        mid = self.incr_mid()
        self.room['dealer'] = next_dealer
        self.room['game_round'] = game_round + 1
        game_type = 'gz'
        for member in self.members:
            pub_data = {"b":self.bid, "u":member, "t":"game", "d":{"mid":mid, "act":"game_over", "room_over":room_over, "game_type":game_type, "dealer":dealer, "player_card":player_card, "game_round":game_round, "rid":self.rid,}}
            nsq_pub(pub_data)
            #db.save_game_over(self.rid, game_round, "game_over", member, urllib.quote(json_encode(pub_data).encode("utf-8")))
            #db.commit()
        if room_over == 'y':
            self.dismiss()
        
        
    def dismiss(self, act='room_over'):
        db = dao.Game_DB()
        player_stat = []
        p_stat = db.player_stat(self.rid)
        if p_stat:
            winner = p_stat[-1]['uid']
            max_score = p_stat[-1]['score']
            for ps in p_stat:
                if ps['score'] == max_score:
                    is_winner = 'y'
                else:
                    is_winner = 'n'
                player_stat.append({"uid":ps['uid'], "is_winner":is_winner,"max_prize":str(ps['max_prize']), "max_score":str(ps['max_score']), "lose_num":str(ps['lose_num']), "score":str(ps['score']), "win_num":str(ps['win_num'])})
        else:
            winner = ""
            for uid in self.members:
                player_stat.append({"uid":uid, "max_prize":"0","max_score":"0","lose_num":"0","score":"0","win_num":"0", "is_winner":"n"})
                
        room_info = db.get_room(self.rid, self.bid)
        admin = room_info['admin']
        #gid = room_info['gid']
        #if not gid:
        #    gid = 0
        #for ps in player_stat:
        #    if ps['uid'] == winner:
        #        is_winner = 'y'
        #    else:
        #        is_winner = 'n'
        #    db.add_room_stat(match_id, gid, self.rid, ps['uid'], ps['score'], is_winner)
        #    db.commit()
        for uid in self.members:
            if not uid:
                continue
            pub_data = {"b":self.bid, "u":str(uid), "t":"game", "d":{"act":"room_over", "rid":self.rid, "player_stat":player_stat, "winner":winner, "admin":admin}}
            #db.save_game_over(self.rid, 0, "room_over", uid, json_encode(pub_data))
            #db.commit()
            nsq_pub(pub_data)
        db.dismiss_room(self.rid)
        db.commit()
        for member in self.members:
            member_player = Player(member, self.bid, self.rid)
            member_player.clear()
        redisco.connection.delete("r:%s:current_card" % self.rid)
        redisco.connection.delete("r:%s:out_card" % self.rid)
        redisco.connection.delete("r:%s" % self.rid)
        redisco.connection.delete("r:%s:mid" % self.rid)
        redisco.connection.delete("r:%s:p" % self.rid)
    
